﻿#light

module Dwarf_UnstructuredGrid_Generator

open System
open System.IO
open System.Text
open System.ComponentModel
open System.Globalization   

let Dwarf_UnstructuredGrid_Generator (fs : FileStream, args : String[]) = 
    
    // subsidiary objects
    let writer = new StreamWriter(fs);
    let rand = new Random();       
    
    // constants
    let vertex_size = 15
    let average_triangle_size = 3 * 3
    
    let average_byte_count = vertex_size + average_triangle_size
    let count_of_digits_in_kilobyte = 1024

    // formulaes
    let division x = (float) (x * count_of_digits_in_kilobyte / average_byte_count)
    let dimension x = (int) (Math.Round(division x))

    // current data values
    let count_of_kilobytes = (int) args.[args.Length - 1]
    let current_dimension = dimension count_of_kilobytes
    
    //////////////////////////////////////////////////////////
    
    let epsilon = rand.NextDouble() + 0.00000001;
    
    let numVertex = current_dimension
    let numTriangles = current_dimension / 2
    
    let vertexValues = Array.create<double> numVertex ((double) 0) 
    let triangles = Array2D.zeroCreate<int> numTriangles 3
    
    ////////////////////////////////////////////////////////

    for j = 0 to numVertex - 1 do
        vertexValues.[j]  <- (rand.NextDouble() * (double)100000)
        //vertexValues.[j]  <- (double)(rand.Next() / 10000000)
    
    for j = 0 to numTriangles - 1 do
        triangles.[j, 0] <- Math.Abs(rand.Next() % numVertex)
        triangles.[j, 1] <- Math.Abs(rand.Next() % numVertex)
        triangles.[j, 2] <- Math.Abs(rand.Next() % numVertex)
        
        while triangles.[j, 1] = triangles.[j, 0] do
            triangles.[j, 1] <- Math.Abs(rand.Next() % numVertex)
                                
        while triangles.[j, 2] = triangles.[j, 0] || triangles.[j, 2] = triangles.[j, 1] do
            triangles.[j, 2] <- Math.Abs(rand.Next() % numVertex)
               

    let mutable converted = false
    
    while converted <> true do
        for i = 0 to numVertex - 1 do
            let mutable j = 0
            
            while j < numTriangles && ((triangles.[j, 0] = i || triangles.[j, 1] = i || triangles.[j, 2] = i) = false) do
                j <- j + 1

            if j = numTriangles then
                j <- Math.Abs(rand.Next() % numTriangles)
                let k = Math.Abs(rand.Next() % 3)
                triangles.[j, k] <- i
                triangles.[j, (k + 1) % 3] <- Math.Abs(rand.Next() % numVertex)
                triangles.[j, (k + 2) % 3] <- Math.Abs(rand.Next() % numVertex)
                while triangles.[j, (k + 1) % 3] = triangles.[j, k] do
                    triangles.[j, (k + 1) % 3] <- Math.Abs(rand.Next() % numVertex)
                
                while triangles.[j, (k + 2) % 3] = triangles.[j, k] || triangles.[j, (k + 1) % 3] = triangles.[j, (k + 2) % 3] do
                    triangles.[j, (k + 2) % 3] <- Math.Abs(rand.Next() % numVertex)

                //Console.WriteLine(i + " of " + numVertex);

        for i = 0 to numVertex - 1 do
            converted <- false
            for j = 0 to numTriangles - 1 do
                if triangles.[j, 0] = i || triangles.[j, 1] = i || triangles.[j, 2] = i then
                    converted <- true
                    
    /////////////////////////////////////////////////    

    // write the epsilon
    writer.WriteLine("{0}", epsilon.ToString("F8",CultureInfo.InvariantCulture));
    writer.WriteLine("{0}", numVertex);
    writer.WriteLine("{0}", numTriangles);

    for i = 0 to numVertex - 1 do
        writer.Write("{0} ", vertexValues.[i].ToString("F8", CultureInfo.InvariantCulture));
    writer.WriteLine();

    for i = 0 to 2 do
        for j = 0 to numTriangles - 1 do
            writer.Write("{0} ", triangles.[j, i]);                        
        writer.WriteLine();
        
    writer.Close()

    true